package cn.easier.activity.console.service.impl;

import cn.easier.activity.console.entity.*;
import cn.easier.activity.console.repository.ActivityConsoleUserRepository;
import cn.easier.activity.console.repository.ActivityRoleUserRepository;
import cn.easier.activity.console.repository.ActivityUserInfoRepository;
import cn.easier.activity.console.service.ActivityConsoleUserService;
import cn.easier.activity.web.entity.UserInfo;
import cn.easier.club.base.dto.ResultInfo;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.math.BigInteger;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 后台用户ServiceImpl
 */
@Service
@Transactional
public class ActivityConsoleUserServiceImpl implements ActivityConsoleUserService, UserDetailsService {

    Logger logger = LoggerFactory.getLogger(ActivityConsoleUserServiceImpl.class);

    private static final Pattern PHONE_MATCHER = Pattern.compile("^((13[0-9])|(14[579])|(15([0-3]|[5-9]))|(166)|(17[0135678])|(18[0-9])|(19[8|9]))\\d{8}$");

    private final ActivityConsoleUserRepository activityConsoleUserRepository;
    private final ActivityUserInfoRepository activityUserInfoRepository;
    private final ActivityRoleUserRepository activityRoleUserRepository;

    public ActivityConsoleUserServiceImpl(ActivityConsoleUserRepository activityConsoleUserRepository, ActivityUserInfoRepository activityUserInfoRepository, ActivityRoleUserRepository activityRoleUserRepository) {
        this.activityConsoleUserRepository = activityConsoleUserRepository;
        this.activityUserInfoRepository = activityUserInfoRepository;
        this.activityRoleUserRepository = activityRoleUserRepository;
    }

    @Override
    public ActivityConsoleUser findOne(Integer id) {
        return activityConsoleUserRepository.findOne(id);
    }

    @Override
    public ActivityConsoleUser findByName(String username) {
        ActivityConsoleUser user = activityConsoleUserRepository.findActivityConsoleUserByUsernameAndEnabled(username, true);
        //整理权限(用户表、用户角色表、角色表、角色权限表、权限表，表建成时根据用户拥有的角色调用集合，然后将所有权限加入用户authorities集合,Set会自动去掉角色中重复的权限)
        if (null != user) {
            String[] authorities = user.getAuthoritiesStr().split(",");
            //添加权限
            Set<GrantedAuthority> grantedAuthorities = new HashSet<GrantedAuthority>();
            for (String authority : authorities) {
                grantedAuthorities.add(new SimpleGrantedAuthority(authority));
            }
            user.setAuthorities(grantedAuthorities);
        }
        return user;
    }

    @Override
    public ActivityConsoleUser save(ActivityConsoleUser activityConsoleUser) {
        return activityConsoleUserRepository.save(activityConsoleUser);
    }

    @Override
    public ActivityConsoleUser update(ActivityConsoleUser activityConsoleUser) {
        return activityConsoleUserRepository.saveAndFlush(activityConsoleUser);
    }

    @Override
    public ResultInfo changeEnabled(Integer id, boolean enabled) {
        ActivityConsoleUser byUid = activityConsoleUserRepository.findByUid(Long.valueOf(id));
        if (byUid == null) {
            return new ResultInfo("ERROR", "未查到该用户的用户信息activityConsoleUser", null);
        }
        if (byUid.getAuthoritiesStr().equals("ROLE_USER_SUPERADMIN")) {
            return new ResultInfo("ERROR", "你不能禁用超级管理员", null);
        }
//        UserInfo userInfo = byUsername.get(0);
        if (enabled) {
            byUid.setEnabled(true);
//            userInfo.setFreeze(false);
            activityConsoleUserRepository.save(byUid);
//            activityUserInfoRepository.save(userInfo);
            return new ResultInfo(String.valueOf(HttpServletResponse.SC_OK), "解除禁用成功", null);
        } else {
            byUid.setEnabled(false);
//            userInfo.setFreeze(true);
            activityConsoleUserRepository.save(byUid);
//            activityUserInfoRepository.save(userInfo);
            return new ResultInfo(String.valueOf(HttpServletResponse.SC_OK), "禁用成功", null);
        }
    }

    @Override
    public boolean changeAuthorities(Integer id, Set<ActivityConsoleRole> activityConsoleRoleSet) {
        //用户权限字符串
        String authoritiesStr;
        Set<String> authoritiesSet = new HashSet<String>();
        for (ActivityConsoleRole activityConsoleRole : activityConsoleRoleSet) {
            authoritiesSet.add(activityConsoleRole.getIdentification());
        }
        if (authoritiesSet.size() <= 16) {
            authoritiesStr = StringUtils.join(authoritiesSet, ActivityConsoleUser.DEFAULT_SPLIT);
        } else {
            authoritiesStr = null;
        }
        return activityConsoleUserRepository.changeAuthoritiesStr(id, authoritiesStr) > 0 ? true : false;
    }

    @Override
    public List<ActivityConsoleUser> findAll() {
        return activityConsoleUserRepository.findAll();
    }

    @Override
    public List<Object> getUserMessage(int pageNum, int pageSize, String userName) {
        int pageCount = pageNum * pageSize;
        List<Object> returnList = new ArrayList<>();
        List<Object[]> allBy = activityConsoleUserRepository.findAllBy(userName, pageCount, pageSize);
        long allByCount = activityConsoleUserRepository.findAllByCount(userName);
        for (Object[] objects : allBy) {
            List<String> list1 = new ArrayList<>();
            UserDto userDto = new UserDto();
            userDto.setUid(((BigInteger) objects[0]).longValue());
            userDto.setUsername((String) objects[1]);
            userDto.setPhoneNum(((BigInteger) objects[2]).longValue());
            userDto.setAuthoritiesStr((String) objects[3]);
            userDto.setEnabled((Boolean) objects[4]);
            userDto.setNickName((String) objects[5]);
            userDto.setRegisterDate((Date) objects[6]);
            userDto.setActivity((Integer) objects[7]);
            userDto.setEmail((Integer) objects[8]);
            userDto.setLookData((Integer) objects[9]);
            userDto.setMessage((Integer) objects[10]);
            userDto.setEmailAndSms((Integer) objects[11]);
            if (userDto.getActivity() == 1) {
                list1.add("创建活动");
            }
            if (userDto.getEmail() == 1) {
                list1.add("邮件接口");
            }
            if (userDto.getLookData() == 1) {
                list1.add("查看数据");
            }
            if (userDto.getMessage() == 1) {
                list1.add("短信接口");
            }
            if (userDto.getEmailAndSms() == 1) {
                list1.add("邮短接口");
            }
            userDto.setCheckList(list1);
            returnList.add(userDto);
        }
        returnList.add(allByCount);
        return returnList;
    }

    @Override
    public ResultInfo updateUser(UserParams userParams) {
        ActivityConsoleUser byUid = activityConsoleUserRepository.findByUid(userParams.getUid());
        List<UserInfo> byPhoneNum1 = activityUserInfoRepository.findByPhoneNum(userParams.getPhoneNum() + "");
        List<ActivityRoleUser> byUsername = activityRoleUserRepository.findByUsername(userParams.getUsername());
        if (byUid == null) {
            return new ResultInfo("ERROR", "未查到该用户的用户信息activityConsoleUser", null);
        }
        boolean verificationPhone = this.isPhone(userParams.getPhoneNum() + "");
        if (!verificationPhone) {
            return new ResultInfo("ERROR", "请填写正确的手机号", null);
        }
        List<ActivityConsoleUser> byPhoneNum = activityConsoleUserRepository.findByPhoneNumAndUidIsNot(userParams.getPhoneNum(), userParams.getUid());
        List<ActivityConsoleUser> byNickName = activityConsoleUserRepository.findByNickNameAndUidIsNot(userParams.getNickName(), userParams.getUid());
        if (CollectionUtils.isNotEmpty(byPhoneNum)) {
            return new ResultInfo("ERROR", "您填写的手机号已经被注册", null);
        }
        if (CollectionUtils.isNotEmpty(byNickName)) {
            return new ResultInfo("ERROR", "您填写的昵称已经被注册", null);
        }
        byUid.setAuthoritiesStr("ROLE_" + userParams.getAuthoritiesStr());
        String newPassword = new BCryptPasswordEncoder().encode(userParams.getPassword());
        byUid.setPassword(newPassword);
        byUid.setNickName(userParams.getNickName());
        byUid.setPhoneNum(userParams.getPhoneNum());
        activityConsoleUserRepository.save(byUid);
        if (CollectionUtils.isNotEmpty(byPhoneNum1)) {
            UserInfo userInfo = byPhoneNum1.get(0);
            userInfo.setAuthoritiesStr("ROLE_" + userParams.getAuthoritiesStr());
            activityUserInfoRepository.save(userInfo);
        }
        if (CollectionUtils.isNotEmpty(userParams.getCheckList())) {
            List<String> checkList = userParams.getCheckList();
            ActivityRoleUser activityRoleUser = byUsername.get(0);
            if (checkList.contains("创建活动")) {
                activityRoleUser.setActivity(1);
            } else {
                activityRoleUser.setActivity(0);
            }
            if (checkList.contains("查看数据")) {
                activityRoleUser.setLookData(1);
            } else {
                activityRoleUser.setLookData(0);
            }
            if (checkList.contains("短信接口")) {
                activityRoleUser.setMessage(1);
            } else {
                activityRoleUser.setMessage(0);
            }
            if (checkList.contains("邮件接口")) {
                activityRoleUser.setEmail(1);
            } else {
                activityRoleUser.setEmail(0);
            }
            if (checkList.contains("邮短接口")) {
                activityRoleUser.setEmailAndSms(1);
            } else {
                activityRoleUser.setEmailAndSms(0);
            }
            activityRoleUser.setPhoneNum(userParams.getPhoneNum());
            activityRoleUserRepository.save(activityRoleUser);
        }
        return new ResultInfo(String.valueOf(HttpServletResponse.SC_OK), "SUCCESS", null);
    }

    @Override
    public ResultInfo saveMessage(UserParams userParams) {
        try {
            // activity_console_user
            String password = userParams.getPassword();
            //密文加密 new BCryptPasswordEncoder()
            password = new BCryptPasswordEncoder().encode(password);
            ActivityConsoleUser activityConsoleUser = new ActivityConsoleUser();
            activityConsoleUser.setPassword(password);
            activityConsoleUser.setRegisterDate(new Date());
            activityConsoleUser.setEnabled(true);
            activityConsoleUser.setAuthoritiesStr("ROLE_" + userParams.getAuthoritiesStr());
            activityConsoleUser.setUsername(userParams.getUsername());
            activityConsoleUser.setSex("");
            activityConsoleUser.setNickName(userParams.getNickName());
            activityConsoleUser.setPhoneNum(userParams.getPhoneNum());
            ActivityConsoleUser returnActivityTemplateInfo = activityConsoleUserRepository.save(activityConsoleUser);
            //activity_user_info
            List<UserInfo> byPhoneNum = activityUserInfoRepository.findByPhoneNum(userParams.getPhoneNum() + "");
            if (CollectionUtils.isNotEmpty(byPhoneNum)) {
                UserInfo userInfo = byPhoneNum.get(0);
                userInfo.setUsername(userParams.getUsername());
                userInfo.setAuthoritiesStr("ROLE_" + userParams.getAuthoritiesStr());
                activityUserInfoRepository.save(userInfo);
            }
            //activity_role_user
            ActivityRoleUser activityRoleUser = new ActivityRoleUser();
            activityRoleUser.setPhoneNum(userParams.getPhoneNum());
            activityRoleUser.setUpdateDate(new Date());
            activityRoleUser.setUsername(userParams.getUsername());
            List<String> checkList = userParams.getCheckList();
            for (String s : checkList) {
                if (s.equals("创建活动")) {
                    activityRoleUser.setActivity(1);
                }
                if (s.equals("查看数据")) {
                    activityRoleUser.setLookData(1);
                }
                if (s.equals("短信接口")) {
                    activityRoleUser.setMessage(1);
                }
                if (s.equals("邮件接口")) {
                    activityRoleUser.setEmail(1);
                }
                if (s.equals("邮短接口")) {
                    activityRoleUser.setEmailAndSms(1);
                }
            }
            activityRoleUserRepository.save(activityRoleUser);
            logger.info("注册用户成功: =>{}", returnActivityTemplateInfo);
            return new ResultInfo(String.valueOf(HttpServletResponse.SC_OK), "SUCCESS", returnActivityTemplateInfo);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("注册用户异常,activityConsoleUser: =>{}", e);
            return new ResultInfo(String.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), "注册用户异常", null);
        }
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        ActivityConsoleUser user = activityConsoleUserRepository.findActivityConsoleUserByUsernameAndEnabled(username, true);
        //如果存在用户，那么添加权限集合然后返回
        if (null != user) {
            //todo 目前暂时把权限添加到用户权限字符串中，并且权限表会存储完整数据。如果权限字符串数据为null，可以调用权限表数据。
            Set<GrantedAuthority> grantedAuthorities = new HashSet<GrantedAuthority>();
            //如果用户权限字符串不为空则获取，否则从权限表关联获取用户所有权限
            if (null != user.getAuthoritiesStr()) {
                String[] authorities = user.getAuthoritiesStr().split(ActivityConsoleUser.DEFAULT_SPLIT);
                for (String authority : authorities) {
                    grantedAuthorities.add(new SimpleGrantedAuthority(authority));
                }
            } else {
                //todo 从权限表关联获取用户所有权限
            }
            user.setAuthorities(grantedAuthorities);
            return user;
        }
        throw new UsernameNotFoundException("User name" + username + "not find");
    }

    @Override
    public ActivityRoleUser getUserRole(String userName) {
        List<ActivityRoleUser> roleUserList = activityRoleUserRepository.findByUsername(userName);
        if (roleUserList.size() > 0) {
            return roleUserList.get(0);
        }
        return null;
    }

    private boolean isPhone(String phone) {
        if (phone.length() != 11) {
            return false;
        } else {
            Matcher m = PHONE_MATCHER.matcher(phone);
            return m.matches();
        }
    }
}
